/** \file vetor.hpp
 *  \brief Definição da classe vetor e de algumas funções e operadores relacionados à algebra vetorial
 *  \author Geraldo Francisco de S. Rebouças | gfs.reboucas@gmail.com
 *  \since 28/11/2012
 *  \version 1.0
 *  \date 02/12/2012
 *  \see Veja [Matrix Computations] e [Applied Linear Algebra] para entender a teoria relacionada à implementação desta classe. */

#ifndef _VETOR_HPP // Diretrizes de pré-processamento para compilação condicional. Se vetor.hpp não foi definido, defina vetor.hpp. Isso evita a inserção duplicada de uma biblioteca num mesmo código-fonte.
#define _VETOR_HPP

#include <valarray>

#include "matriz.hpp"

# define scout cout << scientific ///< Facilita a impressão de dados no formato científico

using namespace std;

class matriz;

/** \class vetor
 *  \brief Classe para operações vetoriais diversas */
class vetor
{
    private:
        int dim; ///< Dimensão do vetor, a quantidade de elementos
        bool trp; ///< Indica se o vetor é transposto ou não
        valarray <double> v; ///< Estrutura de dados que armazena os elementos do vetor
//        valarray <complex <double> > vc; ///< Estrutura de dados que irá armazenar os elementos de um vetor complexo

    public:
        vetor(); ///< Construtor default
        ~vetor(); ///< Destrutor
        vetor(int); ///< Construtor 00, define apenas a quantidade de elementos do vetor
        vetor(int, bool); ///< Construtor 01, define apenas a quantidade de elementos e se o vetor é linha ou coluna
        vetor(double*, int, bool); ///< Construtor 02, faz o mesmo que o 01 e inicializa v com base num array
        vetor(valarray <double>, bool); ///< Construtor 03, faz o mesmo que o 01, e inicializa v com base num valarray
        vetor(const vetor &); ///< Construtor de cópia
        void setNull(int); ///< Anula os primeiros \f$ k \f$ elementos do vetor
        void show(); ///< Exibe os elementos do vetor
        void set(int, bool); ///< Igual ao construtor 01, mas v é inserido diretamente pelo usuário em tempo de execução
        double norma(int); ///< Calcula a norma \f$ i \f$ do vetor
        double normaInf(); ///< Calcula a norma infinita do vetor
        int retDim(); ///< Retorna a dimensão do vetor
        bool retTr(); ///< Retorna o tipo do vetor, linha ou coluna
        vetor minivec(int, int); ///< Retorna um vetor igual ao original indo da linha \f$ a \f$ a \f$ b \f$ ,  \f$ v_{a:b} \f$
        vetor& operator+=(const vetor &); ///< Retorna a soma entre dois vetores, armazenando o resultado no primeiro deles
        vetor& operator=(const vetor &);  ///< Operador de atribuição, torna um vetor igual ao outro  \f$ a = b \f$
        vetor operator-(); ///< Retorna o inverso aditivo do vetor: \f$ -v \f$
        double& operator()(int); ///< Retorna o i-ésimo elemento do vetor: \f$ v_i \f$
};

vetor zero(int, bool); ///< Retorna um vetor nulo de dimensão k:  \f$ 0_k \f$
vetor operator*(double, vetor); ///< Retorna o produto entre uma constante e um vetor: \f$ k v \f$
vetor operator*(vetor, double); ///< Retorna o produto entre um vetor e uma constante: \f$ v k \f$
double operator^(vetor, vetor); ///< Retorna o produto interno entre dois vetores: \f$ a \dot b \f$
vetor operator*(vetor, vetor); ///< Retorna o produto vetorial entre dois vetores: \f$ a \times b \f$
vetor operator+(vetor, vetor); ///< Retorna a soma entre dois vetores: \f$ a + b \f$
vetor operator-(vetor, vetor); ///< Retorna a subtração entre dois vetores: \f$ a - b \f$
vetor operator*(vetor, matriz); ///< Retorna o produto entre um vetor e uma matriz: \f$ v M \f$
vetor operator*(matriz, vetor); ///< Retorna o produto entre uma matriz e um vetor: \f$ M v \f$
ostream& operator<<(ostream&, vetor); ///< Imprime os elementos do vetor numa linha, utilizado apenas p/ saídas em arquivo

#endif // _VETOR_HPP
